package com.mind.core.net.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import org.apache.log4j.Logger;

import com.mind.core.log.ServerStatusLog;
import com.mind.core.net.codec.GameDecoder;
import com.mind.core.net.codec.GameEncoder;
import com.mind.core.net.processor.IMessageProcessor;
import com.mind.core.server.ShutdownHooker;

public class SocketClient {
	private static final Logger logger = Logger.getLogger(SocketClient.class);
	private final static ShutdownHooker hooker = new ShutdownHooker();
	private Bootstrap bootstrap;
	private String host;
	private int port;
	private final IMessageProcessor messageProcessor;
	public SocketClient(String host, int port,IMessageProcessor messageProcessor,
			final AbstractIoClientHandler ioHandler) {
		this.host = host;
		this.port = port;
		this.messageProcessor=messageProcessor;
		messageProcessor.start();
		startServices();
		EventLoopGroup group = new NioEventLoopGroup();
		bootstrap = new Bootstrap();
		bootstrap.group(group).channel(NioSocketChannel.class)
				.handler(new ChannelInitializer<SocketChannel>() {
					@Override
					public void initChannel(SocketChannel ch)
							throws Exception {
						ch.pipeline().addLast(
								new GameDecoder(),
								new GameEncoder(), ioHandler);
					}
				})
				.option(ChannelOption.TCP_NODELAY, true);

	}

	public void connect() {
		try {
			bootstrap.connect(host, port).sync().channel();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	public void startServices() {
		// 停机时停止主线程的处理
		hooker.register(new Runnable() {
			@Override
			public void run() {
				logger.info("正在关闭服务");
			}
		});
		// 增加JVM停机时的处理
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				try {
					ServerStatusLog.getDefaultLog().logStoppping();
					hooker.run();
				} finally {
					ServerStatusLog.getDefaultLog().logStopped();
				}
			}
		});
	}
}
